package com.tanhua.manager.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanhua.manager.domain.AnalysisByDay;
import com.tanhua.manager.domain.Log;
import com.tanhua.manager.mapper.AnalysisByDayMapper;
import com.tanhua.manager.mapper.LogMapper;
import com.tanhua.manager.utils.ComputeUtil;
import com.tanhua.manager.vo.AnalysisChartDataItem;
import com.tanhua.manager.vo.AnalysisChartDataVO;
import com.tanhua.manager.vo.AnalysisSummaryVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class AnalysisService extends ServiceImpl<AnalysisByDayMapper, AnalysisByDay> {
   @Autowired
   private LogMapper logMapper;

    //首页--概要信息统计
    public ResponseEntity summary() {
        AnalysisSummaryVO vo = new AnalysisSummaryVO();
        //1. cumulativeUsers 累计用户
    long  cumulativeUsers=this.baseMapper.queryCumulativeUsers();
     vo.setCumulativeUsers(cumulativeUsers);
        //2. activePassMonth 过去30天活跃数
        Date now = new Date();
        String nowStr = new DateTime(now).toString("yyyy-MM-dd");
        String date30 = DateUtil.offsetDay(now, -30).toString("yyyy-MM-dd");
        long activePassMonth=this.baseMapper.queryActiveUsers(date30,nowStr);
        vo.setActivePassMonth(activePassMonth);


        //3. activePassWeek 过去7天活跃数
        String date7 = DateUtil.offsetDay(now, -7).toString("yyyy-MM-dd");
        long activePassWeek= this.baseMapper.queryActiveUsers(date7,nowStr);
        vo.setActivePassWeek(activePassWeek);
        //4. newUsersToday 今日新增用户
        AnalysisByDay analysisToday = query().eq("record_date", nowStr).one();
        Integer newUsersToday = analysisToday.getNumRegistered();
        vo.setNewUsersToday(newUsersToday.longValue());


        //5. newUsersTodayRate 今日新增用户涨跌率
        String yesterday = DateUtil.offsetDay(now, -1).toString("yyyy-MM-dd");
        AnalysisByDay analysisYesterday = query().eq("record_date", yesterday).one();
        Integer newUsersYesterday = analysisYesterday.getNumRegistered();
        BigDecimal newUsersTodayRate = ComputeUtil.computeRate(newUsersToday.longValue(), newUsersYesterday.longValue());
        vo.setNewUsersTodayRate(newUsersTodayRate);

        //6. loginTimesToday 今日登录次数
        Integer loginTimesToday = analysisToday.getNumLogin();
        vo.setLoginTimesToday(loginTimesToday.longValue());

        //7. loginTimesTodayRate 今日登录次数涨跌率
        Integer loginTimesYesterday = analysisYesterday.getNumLogin();
        BigDecimal loginTimesTodayRate = ComputeUtil.computeRate(loginTimesToday.longValue(), loginTimesYesterday.longValue());
        vo.setLoginTimesTodayRate(loginTimesTodayRate);


        //8. activeUsersToday 今日活跃用户
        Integer activeUsersToday = analysisToday.getNumActive();
        vo.setActiveUsersToday(activeUsersToday.longValue());

        //9. activeUsersTodayRate 今日活跃用户涨跌率
        Integer activeUsersYesterday = analysisYesterday.getNumActive();
        BigDecimal activeUsersTodayRate = ComputeUtil.computeRate(activeUsersToday.longValue(), activeUsersYesterday.longValue());
        vo.setActiveUsersTodayRate(activeUsersTodayRate);
        return ResponseEntity.ok(vo);
    }

   /**
    * 首页-折线图数据（新增、活跃用户、次日留存率）
    * GET /dashboard/users
    * @param sd 开始时间，毫秒值
    * @param ed 结束时间，毫秒值
    * @param type 操作类型。101新增，102活跃用户，103次日留存率
    */
   public ResponseEntity usersChartData(Long sd, Long ed, Integer type) {
      AnalysisChartDataVO vo = new AnalysisChartDataVO();
      
      //1.今年的数据
      //1.1准备查询的日期范围
      String startDateThisYear = DateUtil.date(sd).toString("yyyy-MM-dd");
      String endDateThisYear = DateUtil.date(ed).toString("yyyy-MM-dd");
      //1.2从数据库中查询日期范围的数据
      List<AnalysisByDay> analysisListThisYear = query().between("record_date", startDateThisYear, endDateThisYear).list();
      //1.3把每天的数据转换成AnalysisChartDataItem对象
      List<AnalysisChartDataItem> thisYearList = new ArrayList<>();
      for (AnalysisByDay analysis : analysisListThisYear) {
         AnalysisChartDataItem item = new AnalysisChartDataItem();
         item.setTitle(DateUtil.format(analysis.getRecordDate(),"yyyy-MM-dd"));
         if (type==101){
            item.setAmount(analysis.getNumRegistered().longValue());
         }else if (type==102){
             item.setAmount(analysis.getNumActive().longValue());

         }else if (type==103){
            item.setAmount(analysis.getNumRetention1d().longValue());
         }
         thisYearList.add(item);

      }
      //把今年的AnalysisChartDataItem集合，放到vo的thisYear里
      vo.setThisYear(thisYearList);
      
      //2.去年的数据
      //2.1准备去年的日期范围
      String startDateLastYear = DateUtil.date(sd).offset(DateField.YEAR, -1).toString("yyyy-MM-dd");
      String endDateLastYear = DateUtil.date(ed).offset(DateField.YEAR, -1).toString("yyyy-MM-dd");
      //从数据库查询指定范围的数据
      List<AnalysisByDay> analysisListLastYear = query().between("record_date", startDateLastYear, endDateLastYear).list();
      //把去年每天的数据转换成AnalysisChartDataItem对象
      ArrayList<AnalysisChartDataItem> lastYearList = new ArrayList<>();
      for (AnalysisByDay analysis : analysisListLastYear) {
         AnalysisChartDataItem item = new AnalysisChartDataItem();
         item.setTitle(DateUtil.format(analysis.getRecordDate(),"yyyy-MM-dd"));
         if (type==101){
            item.setAmount(analysis.getNumRegistered().longValue());

         }else if (type==102){
            item.setAmount(analysis.getNumActive().longValue());
         }else  if (type==103){
            item.setAmount(analysis.getNumRetention1d().longValue());
         }
         lastYearList.add(item);
      }
      //封装到vo里
      vo.setLastYear(lastYearList);

   return ResponseEntity.ok(vo);
   }

   /**
    * 分析日志，统计分析数据存储到tb_analysis_by_day表
    */
   //每半小时统计一次
   public void analysis() {
      //准备统计日期
      Date now = new Date();
      String today = DateUtil.format(now, "yyyy-MM-dd");
      String yesterday = DateUtil.offsetDay(now, -1).toString("yyyy-MM-dd");

      //如果统计结果记录不存在，则创建一条
      AnalysisByDay analysis = query().eq("record_date", today).one();
      if (analysis==null){
      analysis=new AnalysisByDay();
      analysis.setRecordDate(now);
      analysis.setCreated(now);
      analysis.setUpdated(now);
      save(analysis);
      }
      //统计数据
      //3.1今日新增用户数
      QueryWrapper<Log> wrapper = new QueryWrapper<>();
      wrapper.eq("TYPE","0102");
      wrapper.eq("log_time",today);
      Integer register = logMapper.selectCount(wrapper);
      analysis.setNumLogin(register);
      //3.2 今日登录次数
      wrapper=new QueryWrapper<>();
      wrapper.eq("TYPE","0101");
      wrapper.eq("log_time",today);
      Integer login = logMapper.selectCount(wrapper);
      analysis.setNumLogin(login);
      //3.3 今日活跃用户数
     wrapper= new QueryWrapper<>();
     wrapper.eq("log_time",today);
     wrapper.select("distinct user_id");
      Integer active = logMapper.selectCount(wrapper);
      analysis.setNumActive(active);

      //3.4 次日留存用户数
      int retention =logMapper.queryRetentionCount(today,yesterday);
      analysis.setNumRetention1d(retention);

      //4 更新到数据库
      updateById(analysis);
   }
}
